#include "Sampler.h"
#include <FL/fl_ask.H>


#define NUMBER_OF_PARAMS 1

//inline
float interpolate_linear( float * data, float x )
{
    float x_int = floor(x); //new double;
    float r = x - x_int; //fractional part of x goes to 'r'
    float *y = &data[(long)x_int];
    return    (y[0] + ( (y[1]-y[0]) * r ));
}


Sampler::Sampler()
//void Sampler::init()
{
    numOfParams = NUMBER_OF_PARAMS;
    open = false;
    filter.SetSampleRate(44100);
    gain = 0.25;
    pos = 0;
    oscRad = 0;
    freq = 1.f;
    speed = 0.999;
    tempo = 150.0f;
    offset = 0.5f;

    bIsPolyphonic = true;

   // sprintf(  filename, "wave\\Linn_tom.wav" );
   // openFile();
}


void Sampler::initMaster()
{
}


void Sampler::newSlave()
{
    Sampler *slave = new Sampler();
    slave->sfinfo = sfinfo;
    slave->sndfile = sndfile;
    slave->open = open;
    slave->data = data;
    slaves.push_back(slave);
}


void Sampler::handleEvent( pluginEvent* event )    //this gets called just before process buffer if there are any events
{
    switch ( event->eventType )
    {
    case EVT_NOTE_ON:
        pos = 0.0f;
        //fInc = freq;
        fInc = event->data->gain + 1;
        //filter.Set((double)(10000*fInc)* event->data->gain * 0.2,0.02);
        //filter.Set(10000*fInc* events->data->gain,0.02);
        gain = 0.5;
        bIsFree = false;
        break;

    case EVT_NOTE_OFF:
        gain = 0.0;
        break;
    }
}

void Sampler::isFree()
{
    if (!open || gain<=0 || (pos>=sfinfo->frames))
        bIsFree = true;
}


void Sampler::processBuffer( float *outputBuffer, unsigned long framesPerBuffer)
{
    if (!open) return;

    float output;

    bool useFilter = false;
    //filter.Set(10000*fInc,0.02);
    //if (fInc<1.9)
    //    useFilter = true;

    for( unsigned long i=0; i<framesPerBuffer; i++ )
    {
        pos += fInc;
        fInc *= 0.9999;
        if (pos<sfinfo->frames)
        {
            if (useFilter)
                 output = gain * filter.Run(interpolate_linear(data, pos));
            else
                 output = gain * interpolate_linear(data, pos);
        }
        else output = 0;

        *outputBuffer++ += output;
        *outputBuffer++ += output; // right
    }
}

void Sampler::openFile()
{
    sfinfo = new SF_INFO;
    sndfile =  sf_open (filename, SFM_READ, sfinfo);

    channels = sfinfo->channels;
    if (channels > 1)
    {
        open = false;
        return;
    }

    data = new float[sfinfo->frames];
    sf_readf_float   (sndfile, data, sfinfo->frames);
    open = true;
}
